use super::dao::{BaseDao, UpdateDao};
use crate::db::po::{
    self,
    network_acl::{ActiveModel, Column, Entity, Model},
};
use sea_orm::{ColumnTrait, DatabaseConnection};
use sea_query::IntoCondition;

#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct Filter {
    pub network_acl_id: Option<String>,
    pub name: Option<String>,
}

impl IntoCondition for Filter {
    fn into_condition(self) -> sea_query::Condition {
        let mut condition = sea_query::Condition::all();
        if let Some(network_acl_id) = self.network_acl_id {
            condition = condition.add(Column::NetworkAclId.eq(network_acl_id));
        }

        if let Some(name) = self.name {
            condition = condition.add(Column::Name.eq(name));
        }
        condition
    }
}

#[derive(Debug, Default, Clone, PartialEq)]
pub struct UpdateParams {
    pub name: po::ActiveValue<String>,
    pub description: po::ActiveValue<String>,
}

impl Into<ActiveModel> for UpdateParams {
    fn into(self) -> ActiveModel {
        ActiveModel {
            id: Default::default(),
            network_acl_id: Default::default(),
            name: self.name,
            description: self.description,
            create_timestamp_millis: Default::default(),
            update_timestamp_millis: Default::default(),
        }
    }
}

#[async_trait::async_trait]
pub trait NetworkAclDao:
    BaseDao<
        Model = Model,
        ActiveModel = ActiveModel,
        Entity = Entity,
        Column = Column,
        Filter = Filter,
    > + UpdateDao<UpdateParams = UpdateParams>
{
}

#[derive(Clone)]
pub struct DefaultNetworkAclDao {
    db: DatabaseConnection,
}

impl DefaultNetworkAclDao {
    pub fn new(db: DatabaseConnection) -> Self {
        Self { db }
    }
}

#[async_trait::async_trait]
impl BaseDao for DefaultNetworkAclDao {
    type Model = Model;
    type ActiveModel = ActiveModel;
    type Entity = Entity;
    type Column = Column;
    type Filter = Filter;

    fn db(&self) -> &DatabaseConnection {
        &self.db
    }
}

#[async_trait::async_trait]
impl UpdateDao for DefaultNetworkAclDao {
    type UpdateParams = UpdateParams;
}

#[async_trait::async_trait]
impl NetworkAclDao for DefaultNetworkAclDao {}
